﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using LukeSkywalker.IPNetwork;
using Newtonsoft.Json;
namespace Central_Control.展厅
{
    /// <summary>
    /// AddPC.xaml 的交互逻辑
    /// </summary>
    public partial class AddPC : Window, INotifyPropertyChanged
    {
        bool isManualPage = true;
        Gallery gallery;
        public GalleryButtonInfo galleryButtonInfo;
        private ObservableCollection<PCinfo> pCinfos;
        public ObservableCollection<PCinfo> PCinfos
        {
            get { return pCinfos; }

            set { pCinfos = value; OnPropertyChanged(nameof(PCinfos)); }
        }
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public AddPC(GalleryButtonInfo galleryButtonInfo, Gallery gallery)
        {
            this.gallery = gallery;
            this.galleryButtonInfo = galleryButtonInfo;
            this.DataContext = this;
            InitializeComponent();
            //GetAllLocalIPAddresses();

            //Dictionary<IPAddress, PhysicalAddress> all = GetAllDevicesOnLAN();

            //foreach (KeyValuePair<IPAddress, PhysicalAddress> kvp in all)
            //{
            //    Console.WriteLine("IP : {0}\n MAC {1}", kvp.Key, kvp.Value);
            //    PCinfo pCinfo = new PCinfo();
            //    pCinfo.IP = kvp.Key.ToString();
            //    pCinfo.Mac = kvp.Value.ToString();
            //    //if (IsOnline(pCinfo.IP))
            //    //{
            //    //    pCinfo.isOnline = true;
            //    //}
            //    //else
            //    //{
            //    //    pCinfo.isOnline = false;
            //    //}
            //    PCinfos.Add(pCinfo);

            //}
        }
        public event PropertyChangedEventHandler? PropertyChanged;

        private async Task EnumComputersAsync()
        {
            try
            {
                PCinfos = new ObservableCollection<PCinfo>();
                if (galleryButtonInfo.pcInfos != null)
                {
                    if (galleryButtonInfo.pcInfos.Count > 0)
                    {
                        for (int i = 0; i < galleryButtonInfo.pcInfos.Count; i++)
                        {
                            PCinfo ipMacData = new PCinfo { IP = galleryButtonInfo.pcInfos[i].IP, Mac = galleryButtonInfo.pcInfos[i].MAC, Name = galleryButtonInfo.pcInfos[i].Name, isAdd = galleryButtonInfo.pcInfos[i].isAdd, ID = galleryButtonInfo.pcInfos[i].ID };
                            Dispatcher.Invoke(() =>
                            {
                                // 在 UI 线程上修改集合
                                PCinfos.Add(ipMacData);
                            });
                        }
                    }

                }

                await Task.Run(() =>
                {
                    Parallel.For(1, 256, i =>
                    {
                        string ipAddress = "192.168.10." + i.ToString();

                        // 检查IP地址是否已存在于列表中
                        if (!IsIpInList(ipAddress))
                        {
                            string macAddress = GetMacAddress(ipAddress);

                            if (macAddress != "N/A")
                            {

                                PCinfo ipMacData = new PCinfo { IP = ipAddress, Mac = macAddress };

                                // 检查计算机在线状态并更新IsOnline属性
                                //bool isOnline = CheckComputerOnline(ipAddress);
                                //ipMacData.isOnline = isOnline;
                                Debug.WriteLine("ip:" + ipMacData.IP + "  |  mac:" + ipMacData.Mac + "|" + "ID:" + ipMacData.ID);
                                // 使用 Dispatcher 来确保在 UI 线程上执行
                                Dispatcher.Invoke(() =>
                                {
                                    //if (PCinfos.Count > 0)
                                    //{
                                    //    ipMacData.ID = PCinfos[PCinfos.Count - 1].ID + 1;
                                    //}
                                    //else
                                    //{
                                    //    ipMacData.ID = 0;
                                    //}
                                    // 在 UI 线程上修改集合
                                    PCinfos.Add(ipMacData);
                                });
                                // 添加到数据列表

                            }
                        }
                    });
                });


            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error: " + ex.Message);
            }
        }
        private bool IsIpInList(string ipAddress)
        {
            if (galleryButtonInfo.pcInfos != null && galleryButtonInfo.pcInfos.Count > 0)
            {
                return galleryButtonInfo.pcInfos.Any(data => data.IP == ipAddress);
            }
            else
            {
                return false;
            }

        }

        private string GetMacAddress(string ipAddress)
        {
            try
            {
                IPAddress ip = IPAddress.Parse(ipAddress);
                byte[] macAddr = new byte[6];
                uint macAddrLen = (uint)macAddr.Length;

                int res = SendARP(BitConverter.ToInt32(ip.GetAddressBytes(), 0), 0, macAddr, ref macAddrLen);
                if (res == 0)
                {
                    string macAddress = BitConverter.ToString(macAddr, 0, (int)macAddrLen);
                    return macAddress;
                }
                else
                {
                    return "N/A";
                }
            }
            catch (Exception ex)
            {
                return "N/A";
            }
        }
        private bool CheckComputerOnline(string ipAddress)
        {
            try
            {
                Ping ping = new Ping();
                PingReply reply = ping.Send(ipAddress);

                if (reply != null && reply.Status == IPStatus.Success)
                {
                    return true; // 计算机在线
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error checking computer online status: " + ex.Message);
            }

            return false; // 计算机不在线
        }

        [DllImport("iphlpapi.dll", ExactSpelling = true)]
        public static extern int SendARP(int destIp, int srcIp, byte[] macAddr, ref uint macAddrLen);

        //      public bool IsOnline(string ipAddress)
        //      {
        //          try
        //          {
        //              Ping ping = new Ping();
        //              PingReply reply = ping.Send(ipAddress);

        //              if (reply != null && reply.Status == IPStatus.Success)
        //              {
        //                  return true;
        //              }

        //              return false;
        //          }
        //          catch (PingException)
        //          {
        //              return false;
        //          }
        //      }



        //      private void GetAllLocalIPAddresses()
        //      {
        //          PCinfos = new ObservableCollection<PCinfo>();
        //          //获取本地机器名 
        //          string myHostName = Dns.GetHostName();
        //          //获取本机IP 
        //          string myHostIP = Dns.GetHostEntry(myHostName).AddressList.FirstOrDefault(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)?.ToString();
        //          //截取IP网段
        //          int lastDotIndex = myHostIP.LastIndexOf('.');
        //          string ipDuan = lastDotIndex != -1 ? myHostIP.Remove(lastDotIndex) : myHostIP;
        //          //枚举网段计算机
        //          for (int i = 1; i <= 255; i++)
        //          {
        //              Ping myPing = new Ping();
        //              myPing.PingCompleted += new PingCompletedEventHandler(MyPing_PingCompleted);
        //              string pingIP = ipDuan + "." + i.ToString();
        //              myPing.SendAsync(pingIP, 1000, null);
        //          }

        //      }

        //      private void MyPing_PingCompleted(object sender, PingCompletedEventArgs e)
        //      {
        //          if (e.Reply.Status == IPStatus.Success)
        //          {
        //              PCinfo pCinfo = new PCinfo();
        //              pCinfo.IP = e.Reply.Address.ToString();

        //              PCinfos.Add(pCinfo);
        //          }

        //          // 这里可以在完成Ping后执行其他操作，例如更新UI等
        //      }

        //      //-----------------------------------------------------------------
        //      /// <summary>
        ///// MIB_IPNETROW structure returned by GetIpNetTable
        ///// DO NOT MODIFY THIS STRUCTURE.
        ///// </summary>

        //[StructLayout(LayoutKind.Sequential)]
        //      struct MIB_IPNETROW
        //      {
        //          [MarshalAs(UnmanagedType.U4)]
        //          public int dwIndex;
        //          [MarshalAs(UnmanagedType.U4)]
        //          public int dwPhysAddrLen;
        //          [MarshalAs(UnmanagedType.U1)]
        //          public byte mac0;
        //          [MarshalAs(UnmanagedType.U1)]
        //          public byte mac1;
        //          [MarshalAs(UnmanagedType.U1)]
        //          public byte mac2;
        //          [MarshalAs(UnmanagedType.U1)]
        //          public byte mac3;
        //          [MarshalAs(UnmanagedType.U1)]
        //          public byte mac4;
        //          [MarshalAs(UnmanagedType.U1)]
        //          public byte mac5;
        //          [MarshalAs(UnmanagedType.U1)]
        //          public byte mac6;
        //          [MarshalAs(UnmanagedType.U1)]
        //          public byte mac7;
        //          [MarshalAs(UnmanagedType.U4)]
        //          public int dwAddr;
        //          [MarshalAs(UnmanagedType.U4)]
        //          public int dwType;
        //      }

        //      /// <summary>
        //      /// GetIpNetTable external method
        //      /// </summary>
        //      /// <param name="pIpNetTable"></param>
        //      /// <param name="pdwSize"></param>
        //      /// <param name="bOrder"></param>
        //      /// <returns></returns>
        //      [DllImport("IpHlpApi.dll")]
        //      [return: MarshalAs(UnmanagedType.U4)]
        //      static extern int GetIpNetTable(IntPtr pIpNetTable,
        //                                      [MarshalAs(UnmanagedType.U4)] ref int pdwSize, bool bOrder);

        //      /// <summary>
        //      /// Error codes GetIpNetTable returns that we recognise
        //      /// </summary>
        //      const int ERROR_INSUFFICIENT_BUFFER = 122;
        //      /// <summary>
        //      /// Get the IP and MAC addresses of all known devices on the LAN
        //      /// </summary>
        //      /// <remarks>
        //      /// 1) This table is not updated often - it can take some human-scale time
        //      ///    to notice that a device has dropped off the network, or a new device
        //      ///    has connected.
        //      /// 2) This discards non-local devices if they are found - these are multicast
        //      ///    and can be discarded by IP address range.
        //      /// </remarks>
        //      /// <returns></returns>
        //      private static Dictionary<IPAddress, PhysicalAddress> GetAllDevicesOnLAN()
        //      {
        //          Dictionary<IPAddress, PhysicalAddress> all = new Dictionary<IPAddress, PhysicalAddress>();
        //          // Add this PC to the list...
        //          all.Add(GetIPAddress(), GetMacAddress());
        //          int spaceForNetTable = 0;
        //          // Get the space needed
        //          // We do that by requesting the table, but not giving any space at all.
        //          // The return value will tell us how much we actually need.
        //          GetIpNetTable(IntPtr.Zero, ref spaceForNetTable, false);
        //          // Allocate the space
        //          // We use a try-finally block to ensure release.
        //          IntPtr rawTable = IntPtr.Zero;
        //          try
        //          {
        //              rawTable = Marshal.AllocCoTaskMem(spaceForNetTable);
        //              // Get the actual data
        //              int errorCode = GetIpNetTable(rawTable, ref spaceForNetTable, false);
        //              if (errorCode != 0)
        //              {
        //                  // Failed for some reason - can do no more here.
        //                  throw new Exception(string.Format(
        //                      "Unable to retrieve network table. Error code {0}", errorCode));
        //              }
        //              // Get the rows count
        //              int rowsCount = Marshal.ReadInt32(rawTable);
        //              IntPtr currentBuffer = new IntPtr(rawTable.ToInt64() + Marshal.SizeOf(typeof(Int32)));
        //              // Convert the raw table to individual entries
        //              MIB_IPNETROW[] rows = new MIB_IPNETROW[rowsCount];
        //              for (int index = 0; index < rowsCount; index++)
        //              {
        //                  rows[index] = (MIB_IPNETROW)Marshal.PtrToStructure(new IntPtr(currentBuffer.ToInt64() +
        //                                                                                (index * Marshal.SizeOf(typeof(MIB_IPNETROW)))
        //                                                                               ),
        //                                                                     typeof(MIB_IPNETROW));
        //              }
        //              // Define the dummy entries list (we can discard these)
        //              PhysicalAddress virtualMAC = new PhysicalAddress(new byte[] { 0, 0, 0, 0, 0, 0 });
        //              PhysicalAddress broadcastMAC = new PhysicalAddress(new byte[] { 255, 255, 255, 255, 255, 255 });
        //              foreach (MIB_IPNETROW row in rows)
        //              {
        //                  IPAddress ip = new IPAddress(BitConverter.GetBytes(row.dwAddr));
        //                  byte[] rawMAC = new byte[] { row.mac0, row.mac1, row.mac2, row.mac3, row.mac4, row.mac5 };
        //                  PhysicalAddress pa = new PhysicalAddress(rawMAC);
        //                  if (!pa.Equals(virtualMAC) && !pa.Equals(broadcastMAC) && !IsMulticast(ip))
        //                  {
        //                      //Console.WriteLine("IP: {0}\t\tMAC: {1}", ip.ToString(), pa.ToString());
        //                      if (!all.ContainsKey(ip))
        //                      {
        //                          all.Add(ip, pa);
        //                      }
        //                  }
        //              }
        //          }
        //          finally
        //          {
        //              // Release the memory.
        //              Marshal.FreeCoTaskMem(rawTable);
        //          }
        //          return all;
        //      }

        //      /// <summary>
        //      /// Gets the IP address of the current PC
        //      /// </summary>
        //      /// <returns></returns>
        //      private static IPAddress GetIPAddress()
        //      {
        //          String strHostName = Dns.GetHostName();
        //          IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
        //          IPAddress[] addr = ipEntry.AddressList;
        //          foreach (IPAddress ip in addr)
        //          {
        //              if (!ip.IsIPv6LinkLocal)
        //              {
        //                  return (ip);
        //              }
        //          }
        //          return addr.Length > 0 ? addr[0] : null;
        //      }

        //      /// <summary>
        //      /// Gets the MAC address of the current PC.
        //      /// </summary>
        //      /// <returns></returns>
        //      private static PhysicalAddress GetMacAddress()
        //      {
        //          foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
        //          {
        //              // Only consider Ethernet network interfaces
        //              if (nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet &&
        //                  nic.OperationalStatus == OperationalStatus.Up)
        //              {
        //                  return nic.GetPhysicalAddress();
        //              }
        //          }
        //          return null;
        //      }

        //      /// <summary>
        //      /// Returns true if the specified IP address is a multicast address
        //      /// </summary>
        //      /// <param name="ip"></param>
        //      /// <returns></returns>
        //      private static bool IsMulticast(IPAddress ip)
        //      {
        //          bool result = true;
        //          if (!ip.IsIPv6Multicast)
        //          {
        //              byte highIP = ip.GetAddressBytes()[0];
        //              if (highIP < 224 || highIP > 239)
        //              {
        //                  result = false;
        //              }
        //          }
        //          return result;
        //      }

        bool CheckInputContent()
        {
            if (IPInput.Text == string.Empty || MacInput.Text == string.Empty)
            {
                MessageBox.Show("IP和Mac地址不能为空", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return true;
            }
            else
            {
                return false;
            }
        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            if (sender is CheckBox checkBox && checkBox.DataContext is PCinfo pcInfo)
            {
                pcInfo.isAdd = true;
            }
        }

        private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            if (sender is CheckBox checkBox && checkBox.DataContext is PCinfo pcInfo)
            {
                pcInfo.isAdd = false;
            }
        }

        private void Confrim(object sender, RoutedEventArgs e)
        {
            List<PcInfo> pcInfos = new List<PcInfo>();
            if (galleryButtonInfo.AddPcInfos == null)
            {
                galleryButtonInfo.AddPcInfos = new List<PcInfo>();
            }
            if (isManualPage)
            {
                if (CheckInputContent())
                {
                    return;
                }
                else
                {
                    PCinfo getpc = PCinfos.FirstOrDefault(pc => pc.IP == IPInput.Text);
                    if (getpc != null && getpc.isAdd)
                    {
                        MessageBox.Show("改IP设备以添加", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                        return;
                    }
                    else if (getpc != null && !getpc.isAdd)
                    {
                        getpc.isAdd = true;
                    }

                    PcInfo pcInfo = new PcInfo { IP = IPInput.Text, MAC = MacInput.Text, isAdd = true };
                    if (galleryButtonInfo.AddPcInfos != null && galleryButtonInfo.AddPcInfos.Count > 0)
                    {
                        pcInfo.ID = galleryButtonInfo.AddPcInfos[galleryButtonInfo.AddPcInfos.Count - 1].ID + 1;
                    }
                    else
                    {
                        pcInfo.ID = 0;
                    }
                    if (NameInput.Text == string.Empty)
                    {
                        pcInfo.Name = "未命名";
                    }
                    else
                    {
                        pcInfo.Name = NameInput.Text;
                    }
                    galleryButtonInfo.AddPcInfos.Add(pcInfo);

                }
            }
            if (PCinfos != null && PCinfos.Count > 0)
            {
                for (int i = 0; i < PCinfos.Count; i++)
                {
                    PcInfo pcInfo = new PcInfo { IP = PCinfos[i].IP, MAC = PCinfos[i].Mac, Name = PCinfos[i].Name, isAdd = PCinfos[i].isAdd };
                    pcInfos.Add(pcInfo);
                    if (PCinfos[i].isAdd)
                    {
                        PcInfo getpcinfo = galleryButtonInfo.AddPcInfos.FirstOrDefault(button => button.IP == PCinfos[i].IP);
                        if (getpcinfo == null)
                        {
                            if (galleryButtonInfo.AddPcInfos != null && galleryButtonInfo.AddPcInfos.Count > 0)
                            {
                                pcInfo.ID = galleryButtonInfo.AddPcInfos[galleryButtonInfo.AddPcInfos.Count - 1].ID + 1;
                            }
                            else
                            {
                                pcInfo.ID = 0;
                            }
                            galleryButtonInfo.AddPcInfos.Add(pcInfo);
                        }

                    }
                    else
                    {
                        if (galleryButtonInfo.AddPcInfos != null && galleryButtonInfo.AddPcInfos.Count > 0)
                        {
                            PcInfo getpcinfo = galleryButtonInfo.AddPcInfos.FirstOrDefault(button => button.IP == PCinfos[i].IP);
                            if (getpcinfo != null)
                            {
                                galleryButtonInfo.AddPcInfos.Remove(getpcinfo);
                            }
                        }

                    }
                }
            }
            GalleryButtonInfo result = MainWindow.instance.Buttons.FirstOrDefault(button => button.ID == galleryButtonInfo.ID);
            if (result != null)
            {
                result.pcInfos = pcInfos;
                result.AddPcInfos = galleryButtonInfo.AddPcInfos;
                MainWindow.instance.SaveGalleryButtonInfoToJson();
            }
            gallery.InitPC();
            this.Close();
        }

        private void Manual(object sender, RoutedEventArgs e)
        {
            ManualPage.Visibility = Visibility.Visible;
            AutoPage.Visibility = Visibility.Hidden;
            isManualPage = true;
        }

        private void Auto(object sender, RoutedEventArgs e)
        {
            ManualPage.Visibility = Visibility.Hidden;
            AutoPage.Visibility = Visibility.Visible;
            isManualPage = false;
            EnumComputersAsync();
        }

    }

    //public class PCinfo
    //{
    //    public int ID { get; set; }
    //    public string Name { get; set; }
    //    public string IP { get; set; }
    //    public string Mac { get; set; }
    //    public bool isAdd { get; set; }
    //    public bool isOnline { get; set; }
    //}
}

